package cn.south.campus.business.service.impl;

import cn.south.campus.business.config.TokenConfig;
import cn.south.campus.business.model.bo.LoginContext;
import cn.south.campus.business.model.bo.LoginInfo;
import cn.south.campus.business.model.req.LoginReq;
import cn.south.campus.business.model.vo.LoginVO;
import cn.south.campus.business.model.vo.UserVo;
import cn.south.campus.business.service.LoginService;
import cn.south.campus.business.service.StudentService;
import cn.south.campus.business.service.UserService;
import cn.south.campus.business.service.WalletService;
import cn.south.campus.common.cache.CacheService;
import cn.south.campus.common.model.enums.CommonEnums;
import cn.south.campus.common.utils.AssertUtils;
import cn.south.campus.common.utils.GenSerializeUtil;
import cn.south.campus.common.utils.LoggerUtil;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 *
 * </p>
 *
 * @author chow
 * @since 2023/3/14 9:38
 */
@Service
@AllArgsConstructor
public class LoginServiceImpl implements LoginService {

    private final Logger LOG = LoggerFactory.getLogger(LoginServiceImpl.class);

    private CacheService cacheService;

    private UserService userService;

    private StudentService studentService;

    private WalletService walletService;


    @Override
    public String login(LoginReq req) {
        UserVo userVo = userService.selectByPhoneAndPwd(req.getPhone(), req.getPassword());
        AssertUtils.isNotNull(userVo, CommonEnums.PHONE_OR_PWD_ERROR);
        String token = GenSerializeUtil.genToken();
        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setToken(token);
        loginInfo.setId(userVo.getId());
        loginInfo.setNickname(userVo.getNickname());
        loginInfo.setPhone(userVo.getPhone());
        loginInfo.setAvatar(userVo.getAvatar());
        loginInfo.setGender(userVo.getGender());
        LoginContext.setContext(loginInfo);
        cacheService.setCacheObject(token, loginInfo, TokenConfig.EXPIRE);
        return token;
    }


    @Override
    public void logout() {
        LoginInfo context = LoginContext.getContext();
        if (context == null) {
            return;
        }
        boolean deleteObject = cacheService.deleteObject(context.getToken());
        if (!deleteObject) {
            LoggerUtil.error(LOG, "登出失败{0}", context.getPhone());
        }
        LoginContext.remove();
    }

    @Override
    public LoginVO userInfo() {
        LoginInfo context = LoginContext.getContext();
        UserVo userVo = userService.detail(context.getId());
        AssertUtils.isNotNull(userVo, CommonEnums.LOGIN_EXPIRE);
        LoginVO loginVO = new LoginVO();
        loginVO.setNickname(userVo.getNickname());
        loginVO.setAvatar(userVo.getAvatar());
        loginVO.setPhone(userVo.getPhone());
        loginVO.setGender(userVo.getGender());
        loginVO.setId(userVo.getId());
        int status = studentService.getAuthStatus(userVo.getId());
        loginVO.setAuthStatus(status);
        return loginVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(LoginReq req) {
        userService.insert(req);
        UserVo userVo = userService.selectByPhoneAndPwd(req.getPhone(), req.getPassword());
        walletService.initWallet(userVo.getId());
    }
}
